// C++中的static关键字

// =================
// 1. 静态成员变量
// =================
class MyClass {
public:
    static int count; // 声明静态成员变量
};

// 在类外部定义和初始化
int MyClass::count = 0;

// 特点: 
1.属于类而非对象，所有对象共享一个实例
2.必须在类外部定义(除非是const整型或枚举)
3.可以通过类名访问: MyClass::count
4.也可以通过对象访问: obj.count(不推荐)
5.生命周期贯穿整个程序

// 用途: 
1.跟踪类的实例数量
2.共享类的所有实例间的数据
3.实现单例模式的静态实例

// =================
// 2. 静态成员函数
// =================
class MyClass {
public:
    static void printCount() {
        std::cout << "Count: " << count << std::endl;
    }
    
private:
    static int count;
};

// 特点：
1.属于类而非对象
2.只能访问静态成员变量和其他静态成员函数
3.没有this指针
4.通过类名调用: MyClass::printCount()
5.也可以通过对象调用: obj.printCount()（不推荐）

// 用途：
1.操作静态成员变量
2.提供不需要对象状态的功能
3.实现工厂方法

// ================= 
// 3. 局部静态变量
// =================
void function() {
    static int callCount = 0; // 只初始化一次
    callCount++;
    std::cout << "Function called " << callCount << " times" << std::endl;
}
// 特点：
1.在第一次执行该声明时初始化
2.生命周期持续到程序结束
3.每次函数调用共享同一个变量
4.线程安全初始化(C++11及以后)

// 用途：
1.保留函数调用之间的状态
2.实现单例模式的函数本地实例
3.避免重复初始化耗时操作

// ================= 
// 4. 静态全局变量/函数
// =================
// 在文件scope.cpp中
static int privateVariable = 42;
static void privateFunction() { /* ... */ }

// 特点：
1.限制变量/函数的可见性只在定义的文件内
2.避免与其他文件中同名标识符冲突
3.不同于static成员, 这是C语言遗留用法

// 用途：
1.创建文件私有的辅助函数
2.隐藏实现细节
3.防止符号名冲突

// ================= 
// 5. 模板中的静态成员
// =================
template <typename T>
class Container {
public:
    static int instanceCount;
};

// 每个模板实例化有自己的静态成员
template <typename T>
int Container<T>::instanceCount = 0;

// 特点：
1.每个模板实例化类型有自己独立的静态成员
2.Container<int>::instanceCount与Container<double>::instanceCount是不同的变量


// ================= 
// 6. C++11中的类内初始化
// =================
class MyClass {
public:
    static constexpr int MAX_SIZE = 100; // 类内初始化constexpr静态成员
    static const int MIN_SIZE = 10;      // 类内初始化const静态成员
};

// 特点：
1.const和constexpr静态整型成员可以在类内初始化
2.constexpr静态成员通常不需要类外定义(有例外情况)

// ================= 
// 7. 静态断言
// =================
static_assert(sizeof(int) >= 4, "Int too small");
虽然使用了static关键字, 但这是一个不同的构造, 用于编译时断言。


// ================= 
// 8. 特殊用例与技巧
// =================

// 静态构造函数/析构函数
// C++不支持静态构造函数，但可以使用以下模式：
class MyClass {
private:
    static MyClass& getInstance() {
        static MyClass instance;  // C++11保证线程安全初始化
        return instance;
    }
    
    // 静态初始化代码
    class Initializer {
    public:
        Initializer() { 
            // 静态初始化代码
            MyClass::getInstance();
        }
    };
    
    static Initializer initializer;
};

MyClass::Initializer MyClass::initializer;

// 静态多态
// 基于编译时多态（不使用虚函数）：
template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
    
    void implementation() {
        std::cout << "Base implementation" << std::endl;
    }
};

class Child : public Base<Child> {
public:
    void implementation() {
        std::cout << "Child implementation" << std::endl;
    }
};


// ================= 
// 9. 最佳实践
// =================

// 使用静态成员的好处
1.避免全局变量带来的命名空间污染
2.将关联的数据和功能组织在一起
3.实现单例和工厂模式
4.跟踪对象数量和资源使用

// 潜在问题
1.初始化顺序: 全局静态对象的初始化顺序在不同编译单元之间是不确定的
2.线程安全: C++11之前, 静态局部变量的初始化不是线程安全的
3.耦合: 过度使用静态成员可能导致类之间的紧耦合
4.测试困难: 静态成员使单元测试变得复杂

// 推荐做法
1.优先使用类内静态成员而非全局变量
2.利用局部静态变量实现线程安全的单例
3.避免在静态成员变量上构建复杂的依赖关系
4.使用constexpr标记编译时可确定的静态常量